package com.huilink.webmail.service.impl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;

import com.huilink.db.DbThreadLocal;
import com.huilink.db.WebMailDAO;
import com.huilink.webmail.service.api.WebMailService;

public class WebMailServiceProxy implements InvocationHandler {

	private static final Logger log = Logger.getLogger(WebMailServiceProxy.class
			.getName());
	private EntityManagerFactory entityMgrFactory;
	private Map<String, Boolean> acceptedMethods = new HashMap<String, Boolean>();
	private Map<String, Boolean> adminOnlyMethods = new HashMap<String, Boolean>();
	
	private WebMailService realService;
	
	public WebMailServiceProxy(EntityManagerFactory emFactory,
			WebMailDAO webMailDao, Executor executor) {
		this.entityMgrFactory  =emFactory;
		realService =  new WebMailServiceImpl(webMailDao,executor);
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		EntityManager mgr = entityMgrFactory.createEntityManager();
		DbThreadLocal.getInstance().setThreadsBlackboard(mgr);
		EntityTransaction tx = mgr.getTransaction();
		try{
			
			tx.begin();
			Object retVal = null;
			log.info("invoking method=" + method);
			retVal = method.invoke(realService, args);
			tx.commit();
			return retVal;
		}catch (InvocationTargetException e) {
			throw e.getCause();
		}finally {
			try {
				if (tx.isActive())
					tx.rollback();
				mgr.close();
			} catch (Exception e) {
				log.log(Level.SEVERE, "Could not close entitymanager", e);
			}
			log.info("done invoking method=" + method);
		}
	
	}

}
